package com.TeacherInfoServer.listener;

import com.TeacherInfoServer.exception.JobNumberNotExistException;
import com.TeacherInfoServer.exception.RecordRepeatedException;
import com.TeacherInfoServer.pojo.DTO.TeacherDTO;
import com.TeacherInfoServer.pojo.entity.WorkExperience;
import com.TeacherInfoServer.pojo.excelImport.WorkExperienceExcel;
import com.TeacherInfoServer.common.service.TeacherService;
import com.TeacherInfoServer.common.service.WorkExperienceService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Data
@Slf4j
@Component
public class WorkExperienceListener implements ReadListener<WorkExperienceExcel> {
    @Autowired
    private WorkExperienceService workExperienceService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private Validator validator;
    private final List<WorkExperience> workExperienceList = new ArrayList<>();
    private final List<WorkExperience> updateList = new ArrayList<>();
    private final List<WorkExperience> addList = new ArrayList<>();
    private final Set<WorkExperienceExcel> workExperienceFormSet = new HashSet<>();
    private Integer record;
    @Override
    public void invoke(WorkExperienceExcel workExperienceExcel, AnalysisContext analysisContext) {
        Set<ConstraintViolation<WorkExperienceExcel>> violations = validator.validate(workExperienceExcel);
        if (violations.isEmpty()){
            TeacherDTO teacherDTO = teacherService.getOne(workExperienceExcel.getTeacherId()).getData();
            if (teacherDTO != null && teacherDTO.getTeacherName().equals(workExperienceExcel.getTeacherName())){
                if (!workExperienceFormSet.contains(workExperienceExcel)){
                    WorkExperience workExperience =
                            new WorkExperience(null,
                                    workExperienceExcel.getTeacherId(),
                                    workExperienceExcel.getUnit(),
                                    workExperienceExcel.getJobs(),
                                    workExperienceExcel.getStartDate(),
                                    workExperienceExcel.getEndDate(),1,null);
                    workExperienceList.add(workExperience);
                    workExperienceFormSet.add(workExperienceExcel);
                } else {
                    throw new RecordRepeatedException();
                }
            } else {
                if (teacherDTO == null) {
                    throw new JobNumberNotExistException();
                } else {
                    throw new RuntimeException("工号与教师名不匹配：" + teacherDTO.getTeacherId());
                }
            }
        } else {
            String errorMessage = violations.iterator().next().getMessage();
            throw new ConstraintViolationException(errorMessage, violations);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        List<WorkExperience> workExperiences = workExperienceService.list();
        workExperienceList.forEach(workExperience -> {
            Optional<WorkExperience> dbWorkExperienceOptional = workExperiences.stream()
                    .peek(dbWorkExperience -> dbWorkExperience.setId(null))
                    .filter(workExperience::equals)
                    .findFirst();
            dbWorkExperienceOptional.ifPresent(dbWorkExperience -> log.info("记录已存在数据库:{}",dbWorkExperience));
            if (dbWorkExperienceOptional.isEmpty()) {
                addList.add(workExperience);
            }
        });
        List<WorkExperience> mergedList = Stream.concat(updateList.stream(), addList.stream())
                .collect(Collectors.toList());
        workExperienceService.saveOrUpdateBatch(mergedList);
        setRecord(mergedList.size());
        initList();
    }

    public void initList(){
        workExperienceList.clear();
        updateList.clear();
        addList.clear();
        workExperienceFormSet.clear();
    }
}
